﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.Net;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Text;
using System.ServiceModel;
using IAOI.Platform.Common.Configuration;
using IAOI.Platform.Common.Diagnostics;

namespace IAOI.Platform.WCF.WCF.Dispatch
{
    public class MessageInspector : IDispatchMessageInspector
    {

        #region IDispatchMessageInspector Members

        /// <summary>
        ///  인바운드 메시지가 수신된 후 메시지가 의도된 작업에 디스패치되기 전에 호출됩니다.
        /// </summary>
        /// <param name="request"> 요청 메시지입니다.</param>
        /// <param name="channel"> 들어오는 채널입니다.</param>
        /// <param name="instanceContext">현재 서비스 인스턴스입니다.</param>
        /// <returns>상태를 상호 연결하는 데 사용되는 개체입니다.이 개체는 System.ServiceModel.Dispatcher.IDispatchMessageInspector.BeforeSendReply(System.ServiceModel.Channels.Message@,System.Object) 메서드에 다시 전달됩니다.</returns>
        public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request,
            System.ServiceModel.IClientChannel channel,
            System.ServiceModel.InstanceContext instanceContext)
        {


            //string Header = null;
            //for (int i = 0; i < OperationContext.Current.IncomingMessageHeaders.Count; i++)
            //{
            //    MessageHeaderInfo h = OperationContext.Current.IncomingMessageHeaders[i];

            //        // Read the value of that header. 
            //        XmlReader xr = OperationContext.Current.IncomingMessageHeaders.GetReaderAtHeader(i);
            //        Header += h.Name + " " +xr.ReadElementContentAsString() + "\r\n";


            //}


            if (request.Headers.MessageId != null)
            {
                Guid tempGuid = Guid.Empty;

                request.Headers.MessageId.TryGetGuid(out tempGuid);

                if (tempGuid == Guid.Empty)
                {
                    request.Properties.Add("SOAID", Guid.NewGuid());
                }
            }
            else
            {
                request.Properties.Add("SOAID", Guid.NewGuid());
            }

            ServiceLogData loggingData = new ServiceLogData();
            //  loggingData.ContextID = new Guid(request.Properties["SOAID"].ToString());
            //  loggingData.StartTime = DateTimeOffset.Now;
            ////  loggingData.InputMessage = request.ToString();
            //  loggingData.State = State.Progress;
            //  loggingData.HostName = "";
            //  loggingData.Action = request.Headers.Action;
            //  loggingData.AbsoluteUri = request.Headers.To.AbsoluteUri;
            //  RemoteEndpointMessageProperty remoteEndpoint = request.Properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
            //  loggingData.CallerIP = remoteEndpoint.Address;


            //  DataBaseLogging.WriteLogging(loggingData);

            if (ConfigurationManager.Settings.MessageLogging.Level != TraceLevel.Off)
                IAOI.Platform.Common.Diagnostics.Listener.MessageListener.InputMessage("", request.ToString());

            

            //if (ConfigurationManager.Settings.Trace.Level != System.ServiceModel.)
            //    IAOI.Platform.Common.Diagnostics.Listener.TraceListener.Begin("", request.ToString());


            return loggingData;//loggingData.ContextID;
        }



        public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply,
            object correlationState)
        {
            ServiceLogData loggingData = correlationState as ServiceLogData;
            //    LogData loggingData = new LogData(); ;
            loggingData.EndTime = DateTimeOffset.Now;
            //    loggingData.OutputMessage = reply.ToString();
            //     loggingData.ContextID = new Guid(correlationState.ToString());// new Guid(reply.Properties["SOAID"].ToString());

            if (reply.IsFault)
            {
                loggingData.State = State.Fail;
            }
            else
            {
                loggingData.State = State.Sucess;
            }
            DataBaseLogging.WriteLogging(loggingData);
        }

        #endregion
    }
}
